home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
050
/
tpstuff2.arc
/
MENU.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1985-07-17
|
6KB
|
188 lines
{ Menu Generator
Author: Michael H. Hughes; Hereby placed in the Public Domain
This program illustrates the function "menu" which generates a very nice
kind of menu display. This general type of menu has been common on Wang
equipment for years, but has not caught on elsewhere. It is a neater and
quicker menu than most of the common types.
Pass the function a list of descriptive lines, and it will display them
on the screen along with a heading and instructions. A pointer is displayed
beside the first line of the list, and that line is highlighted. Press
a key (usually the space-bar) and the pointer will drop one line down the
list. Another key (backspace) will move the pointer back up the list.
Pressing any character key will cause the routine to search for a line
beginning with that character. If found, the pointer will be positioned
on that line. Another key (return/enter) will cause the routine to exit
and return the number of the selected line. Another key (ESC) can be used
as a "cancel" and will return a zero.
Up to 40 items can be displayed. The routine will position them
automatically, using two columns if necessary.
The routine requires a single-keystroke input routine which does not echo
to the screen or require a return/enter to respond. A function suitable
for MSDOS/PCDOS machines is supplied.
The display will look better if you insert the necessary code to turn the
cursor off.
Note the use of a typeless parameter and an absolute address to pass an
array of uknown length to the routine. }
Function menu(number: Integer; Var data): Integer; { Generate Menu Display }
Const llen = 80; { screen line length }
slen = 20; { maximum number items in one column }
maxnumber = 40; { maximum size of list array }
movedownlist = 32; { SPACE key }
moveuplist = 8; { BACKSPACE key }
select = 13; { ENTER/RETURN key }
cancel = 27; { ESC key }
Type listtype=Array[0..maxnumber] Of String[30];
Var list: listtype Absolute data;
posn, len, margin, vmargin, maxlen: Integer;
minlen, count, cnumber: Integer;
ch: Char;
chval: Byte;
Function keyin: Byte; { Single-Key Input Routine (MSDOS/PCDOS) }
Var register: Record { register pack }
AX,BX,CX,DX,BP,SI,DI,DS,ES,FLAG: Integer;
End;
Begin
register.AX := $0700; { call function 07 }
MsDos(register);
keyin := register.AX And $00FF;
End;
Begin { Menu }
{ Display Heading }
ClrScr; LowVideo;
write(chr(27),'[5h'); { ANSI cursor-off command; change as required }
writeln(list[0]); { Title line }
For posn:=1 To llen Do write('='); writeln;
{ Compute positioning parameters }
If number > maxnumber Then number:=maxnumber;
If number <= slen Then len:=number Else len:=slen;
If number > slen Then margin:=1
Else
Begin
maxlen:=0; minlen:=80;
For count:=1 to number Do
Begin
If length(list[count]) > maxlen Then maxlen:=length(list[count]);
If length(list[count]) < minlen Then minlen:=length(list[count])
End;
margin:=34-(maxlen+minlen) Div 4
End;
If number <= slen Then vmargin:=(slen-number) Div 2
Else vmargin:=(slen-(number Div 2)) Div 2;
vmargin:=vmargin+3;
If number > slen Then
Begin
cnumber:=number Div 2;
If odd(number) Then cnumber:=cnumber+1
End
Else cnumber:=number;
{ Display list }
For posn:=1 To cnumber Do
Begin
gotoxy(margin+4,posn+vmargin);
write(list[posn]);
If ((number) > slen) And ((posn+cnumber) <= number) Then
Begin
gotoxy(45,posn+vmargin);
write(list[posn+cnumber])
End;
writeln
End;
{ Display Instructions }
gotoxy(1,24); NormVideo;
writeln('Press SPACE or BACKSPACE or First Letter of Line to Select');
write('Press RETURN or ENTER to run your choice');
{ Pick menu }
posn:=1;
Repeat
{ Display current pick }
gotoxy(((posn-1) Div cnumber)*40+margin,
((posn-1) Mod cnumber)+1+vmargin);
NormVideo;
write(' -> ',list[posn]);
{ Get Keyboard and clear current pick }
chval:=keyin;
gotoxy(((posn-1) Div cnumber)*40+margin,
((posn-1) Mod cnumber)+1+vmargin);
LowVideo;
If chval <> select Then write(' ',list[posn]);
{ Determine new Pick }
If chval = select Then menu:=posn
Else If chval = cancel Then menu:=0
Else If chval = moveuplist Then
If posn > 1 Then posn:=posn-1
Else posn:=number
Else If chval = movedownlist Then
If posn < (number) Then posn:=posn+1
Else posn:=1
Else { Check for first character of line }
Begin
count:=posn;
ch:=UpCase(chr(chval));
Repeat
count:=succ(count);
If count > number Then count:=1
Until (count = posn) Or (ch = UpCase(copy(list[count],1,1)));
posn:=count
End
Until (chval = select) Or (chval = cancel)
End;
{ The following program illustrates the use of MENU as a basic program loader.
The typed constants are used to set up the menu, and can be changed to
provide any desired choice. The program list is simply in the same order as
the descriptive lines. Lines[0] defines the menu heading while progs[0] is
the program to be loaded if the "cancel" key is pressed. }
Const maxlines = 4; { number of lines in menu }
lines: Array[0..maxlines] Of String[30] =
('General Business Menu',
'Accounts Receivable',
'Accounts Payable',
'Payroll',
'General Ledger');
progs: Array[0..maxlines] Of String[30] = { list of programs to load }
('MAINMENU.COM',
'AR.COM',
'AP.COM',
'PA.COM',
'GL.COM');
Var nextprog: File;
Begin { Main Program }
assign(nextprog,progs[menu(maxlines,lines)]);
execute(nextprog)
End.